package com.jargonee.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Locale;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.net.Uri;
import android.net.http.AndroidHttpClient;

public class JargoneeUtils {

	/**
	 * Reverse geocodes and address from a location using a geocoder
	 * 
	 * @param location
	 *            location to reverse geocode
	 * @param geocoder
	 *            Geocoder to user
	 * @return Address
	 * @throws IOException If there are network problems using geocoder
	 * @throws JSONException 
	 */
	public static Address getAddressFromLocationWithGeocoder(Location location, Geocoder geocoder) throws IOException, JSONException {

		// try easy way first
		Address address;
		try {
			address = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1).get(0);
		} catch(IOException ioe) {
			if(ioe.getMessage().equalsIgnoreCase("Service not Available")) {
				address = new Address(Locale.US);
				address.setLatitude(location.getLatitude());
				address.setLongitude(location.getLongitude());
				Uri.Builder uriBuilder = new Uri.Builder();
				uriBuilder = uriBuilder.encodedPath("http://maps.google.com/maps/api/geocode/json");
				uriBuilder = uriBuilder.appendQueryParameter("latlng", location.getLatitude()+ "," + location.getLongitude());
				uriBuilder = uriBuilder.appendQueryParameter("sensor", "false");
				String jsonString = getResponseFromUri(uriBuilder);
				JSONObject json = new JSONObject(jsonString);
				
				// get first result
				JSONArray results = json.getJSONArray("results");
				if(results.isNull(0))
					throw new IOException();
				JSONArray addressComponents = results.getJSONObject(0).getJSONArray("address_components");
				for(int addressComponentIndex=0; addressComponentIndex < addressComponents.length(); addressComponentIndex++) {
					
					// extract types
					JSONObject addressComponent = addressComponents.getJSONObject(addressComponentIndex);
					String type = addressComponent.getJSONArray("types").getString(0);
					if(type.equalsIgnoreCase("country"))
						address.setCountryName(addressComponent.getString("long_name"));
					else if(type.equalsIgnoreCase("administrative_area_level_1"))
						address.setAdminArea(addressComponent.getString("long_name"));
					else if(type.equalsIgnoreCase("administrative_area_level_2"))
						address.setSubAdminArea(addressComponent.getString("long_name"));
					
				}
			} else {
				throw ioe;
			}
		}
		
		return address;
	}

	/**
	 * Return JSON array from passed in URL
	 * @param url url to connect to
	 * @return JSON
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String getResponseFromUri(Uri.Builder uriBuilder) throws ClientProtocolException, IOException {
		// get results from url
		AndroidHttpClient androidHttpClient = AndroidHttpClient.newInstance("Jargonee Android Search");
		HttpGet httpGet = new HttpGet(uriBuilder.build().toString());
		String responseString;
		
		responseString = androidHttpClient.execute(httpGet, new ResponseHandler<String>() {

			// extract string sent back in response
			public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {

				// get entity for reading json
				HttpEntity entity = response.getEntity();
				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));

				// get string and convert to JSON Array
				StringBuilder json = new StringBuilder();
				String line;
				while ((line = bufferedReader.readLine()) != null)
					json.append(line);

				return json.toString();
			}
		});
		
		return responseString;
	}
	
	public static String postBodyToUri(Uri.Builder uriBuilder, String post) throws ClientProtocolException, UnsupportedEncodingException, IOException {
		// post results to url
		AndroidHttpClient androidHttpClient = AndroidHttpClient.newInstance("Jargonee Android Search");
		HttpPost httpPost = new HttpPost(uriBuilder.build().toString());
		HttpEntity httpEntity = new StringEntity(post);
		httpPost.setEntity(httpEntity);
		httpPost.setHeader("Content-type", "application/json");
		
		String responseString = androidHttpClient.execute(httpPost, new BasicResponseHandler());
		
		return responseString;
	}
}
